/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pio.action.administrador.inscripcion;

import DBMS.DataBaseManager;
import DBMS.TableReader;
import clases.ArchivoExcel;
import clases.Configuracion;
import clases.Coordinador;
import clases.Inscripcion;
import clases.Institucion;
import clases.Prueba;
import clases.RegistroPrueba;
import clases.ReporteInscripcion;
import clases.ReporteInscritos;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import org.apache.struts.upload.FormFile;

/**
 *
 * @author andreth
 */
public class GestionarPruebas extends DispatchAction {

    public ActionForward populate(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        request.removeAttribute("Prueba");
        return mapping.findForward("page");
    }

    public ActionForward save(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        Prueba p = (Prueba) form;
        if (!p.valida()) {
            request.setAttribute("Prueba", p);
            return mapping.findForward("failure");
        }
        System.out.println("entrando a leer archivo de pruebas");
        List<RegistroPrueba> pruebas = leerArchivoRegistrosPrueba(p);
        if (pruebas == null) {
            request.setAttribute("Prueba", p);
            return mapping.findForward("failure");
        }

        System.out.println("entrando a leer archivo de clave");
        String clave = leerArchivoClave(p);
        if (clave.equalsIgnoreCase("")) {
            request.setAttribute("Prueba", p);
            return mapping.findForward("failure");
        }

        Integer inscritos = calcularInscritos(pruebas, clave, p.getCorte(), p.getPorcentajeRaven(),
                p.getPorcentajeVerbal(), p.getProcentajeMatematica());
        request.getSession().setAttribute("inscritos", String.valueOf(inscritos));
        request.getSession().setAttribute("registrosPruebas", pruebas);
        request.getSession().setAttribute("corte", p.getCorte());
        // Ahora hay que calcularlos pidiendo confirmacion de los
        // administradores
        return mapping.findForward("calculo");
    }

    private List<RegistroPrueba> leerArchivoRegistrosPrueba(Prueba p) {
        try {
            String path = getPath(p.getPruebas());
            if (path.isEmpty()) {
                p.setMensaje("No seleccionó ningún archivo de Prueba.");
                return null;
            }
            TableReader table = new TableReader(new File(path));
            RegistroPrueba[] tmp = new RegistroPrueba[table.getMaxRows()-1];
            System.out.println("Numero maximo de filas es: " + table.getMaxRows());
            if (table.getMaxRows() > 1) {
                System.out.println("Leyendo encabezado");
                table.setRow(1); //table.read();// LEE ENCABEZADO
            } else {
                p.setMensaje("No seleccionó ningún archivo de pruebas.");
                return null;
            }
            int fila = 0;
            while (table.hasNext()) {
                System.out.println("Leyendo linea de archivo");
                String[] h = table.read();
                imprimirArreglo(h);
                RegistroPrueba rp = new RegistroPrueba();
                try {
                    boolean todoFalse = true;
                    for (int i = 0; i < h.length; ++i) {
                        if (!h[i].isEmpty()) { // hay algo
                            todoFalse = false;
                            break;
                        }
                    }
                    if (todoFalse) {
                        System.out.println("Toda la linea esta vacia");
                        break;
                    }
                    rp.setCedula(h[0]);
                    rp.setRespuestaPrueba(h[1]);
                    rp.setNotaRaven(h[2]);
                } catch (ArrayIndexOutOfBoundsException a) {
                    System.out.println(a);
                }
                tmp[fila] = rp;
                fila++;
            }
            table.finish();
            System.out.println("table.finish() ejecutado no se lee mas" + tmp.length);
            return Arrays.asList(tmp);
        } catch (Exception e) {
            System.out.println(e);
            p.setMensaje("Error: Archivo no soportado o Formato de Excel invalido");
        }
        return null;
    }

    private String leerArchivoClave(Prueba p) {
        try {
            String path = getPath(p.getClave());
            if (path.isEmpty()) {
                p.setMensaje("No seleccionó ningún archivo de clave .");
                return null;
            }
            TableReader table = new TableReader(new File(path));
            String tmp = "";
            System.out.println("Numero maximo de filas es: " + table.getMaxRows());
            if (table.getMaxRows() > 1) {
                System.out.println("Leyendo encabezado");
                table.setRow(1); //table.read();// LEE ENCABEZADO
            } else {
                p.setMensaje("No seleccionó ningún archivo de clave.");
                return null;
            }
            int fila = 0;
            //Solo deberia entrar 1 vez
            while (table.hasNext()) {
                System.out.println("Leyendo linea de archivo");
                String[] h = table.read();
                try {
                    boolean todoFalse = true;
                    for (int i = 0; i < h.length; ++i) {
                        if (!h[i].isEmpty()) { // hay algo
                            todoFalse = false;
                            break;
                        }
                    }
                    if (todoFalse) {
                        System.out.println("Toda la linea esta vacia");
                        break;
                    }
                    tmp = h[0];
                } catch (ArrayIndexOutOfBoundsException a) {
                    System.out.println(a);
                }
            }
            String[] tmp2 = new String[1];
            tmp2[0] = tmp;
            imprimirArreglo(tmp2);
            table.finish();
            System.out.println("table.finish() ejecutado no se lee mas");
            return tmp;
        } catch (Exception e) {
            p.setMensaje("Error: Archivo no soportado o Formato de Excel invalido");
        }
        return null;
    }

    private String getPath(FormFile form) throws IOException {
        String path = "";
        FileOutputStream outputStream = null;
        FormFile formFile = form;
        try {
            path = getServlet().getServletContext().getRealPath("") + "/"
                    + formFile.getFileName();
            outputStream = new FileOutputStream(new File(path));
            outputStream.write(formFile.getFileData());
        } catch (Exception e) {
            System.out.println(e);
            path = "";
            // Do Nothing
        } finally {
            if (outputStream != null) {
                outputStream.close();
            }
        }
        return path;
    }

    private Integer calcularInscritos(List<RegistroPrueba> pruebas, String clave, String corte,
            String porcentajeRaven, String porcentajeVerbal, String procentajeMatematica) {
        System.out.println("Pruebas size" + pruebas.size());
        //Ciclo externo, lo que se hace para cada prueba
        // Inicialmente hay 0  inscritos.
        Integer inscritos = new Integer(0) ;
        Double porcentajeVerbali = Double.parseDouble(porcentajeVerbal);
        Double procentajeMatematicai = Double.parseDouble(procentajeMatematica);
        Double porcentajeRaveni = Double.parseDouble(porcentajeRaven);

        for (RegistroPrueba registroPrueba : pruebas) {
            System.out.println("Respuesta Prueba Cedula" + registroPrueba.getCedula());
            System.out.println("Numero de Respuestas Prueba Respuesta" + registroPrueba.getRespuestaPrueba().length());
            String respuesta = registroPrueba.getRespuestaPrueba();
            Integer notaVerbal = 0;
            Integer notaMatematicas = 0;

            // Inicialmente su nota es 0
            // Matematicas son 20 preguntas y va primero
            // Verbal son 20 preguntas y va despues
            // Raven son 60 y va al final y ya se sabe la nota
            // Substring no toma el ultimo pero si el primero

            String respuestaMatematica = respuesta.substring(0, 20);
            System.out.println("Respuesta Matematica" + respuestaMatematica);
            String respuestaVerbal = respuesta.substring(20, 40);
            System.out.println("Respuesta Verbal" + respuestaVerbal);
            String claveMatematica = clave.substring(0, 20);
            System.out.println("Clave Matematica" + claveMatematica);
            String claveVerbal = clave.substring(20, 40);
            System.out.println("Clave Verbal" + claveVerbal);

            for (int i = 0; i < 20; i++) {
                if (respuestaMatematica.charAt(i) == claveMatematica.charAt(i)) {
                    notaMatematicas++;
                }
                if (respuestaVerbal.charAt(i) == claveVerbal.charAt(i)) {
                    notaVerbal++;
                }
            }

            registroPrueba.setNotaMatematica(Integer.toString(notaMatematicas));
            System.out.println("Nota matematica " + Integer.toString(notaMatematicas));
            registroPrueba.setNotaVerbal(Integer.toString(notaVerbal));
            System.out.println("Nota Verbal" + Integer.toString(notaVerbal));
            Integer notaRaven = Integer.parseInt(registroPrueba.getNotaRaven());
            System.out.println("Nota Raven" + registroPrueba.getNotaRaven());
            // Calculo final 20 preguntas de mate y verb
            // 60 de raven


            Double notaTotal = (notaMatematicas / 20.0 * procentajeMatematicai)
                    + (notaVerbal / 20.0 * porcentajeVerbali)
                    + (notaRaven / 60.0 * porcentajeRaveni);
            System.out.println("Nota total =  " + notaTotal);
            System.out.println("Nota calculada como ="
                    + "(" + notaMatematicas + "/" + "20 *" + procentajeMatematicai + ")"
                    + "+(" + notaVerbal + "/" + "20 *" + porcentajeVerbali + ")"
                    + "+(" + notaRaven + "/" + "60 *" + porcentajeRaveni + ")");
            // Guardar el calculo final como string
            registroPrueba.setNotaTotal(String.valueOf(notaTotal));
            
            // Si saco mas que el corte hay mas inscritos
            System.out.println("Corte = " + corte);
            if (notaTotal >= Double.parseDouble(corte)) {
                inscritos++;
                registroPrueba.setIsInscrito(true);
            }
            System.out.println("Numero de inscritos " + inscritos);
        }
        return inscritos;
    }

    public ActionForward persist(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        DataBaseManager dbms = DataBaseManager.getInstance();
        dbms.eliminarRegistroInscripcion();
        List<RegistroPrueba> pruebas = (List<RegistroPrueba>) request.getSession().getAttribute("registrosPruebas");
        String corte = (String) request.getSession().getAttribute("corte");
        dbms.agregarRegistrosPruebas(pruebas, corte);
        return mapping.findForward("sucess");
    }

    public ActionForward CVS(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        ReporteInscritos reporte = new ReporteInscritos();
        DataBaseManager dbms = DataBaseManager.getInstance();
        reporte.setInscritos(dbms.consultarInscritos());
        String path = Configuracion.getReportesPath() + "reporteinscritos" + ".cvs";
        try {
            File file = new File(path);
            file.createNewFile();
            FileWriter fr = new FileWriter(file);
            fr.write("Cedula, RespuestaPrueba, NotaRaven, NotaVerbal, NotaMatematica, NotaTotal, Inscrito"
                    + "\n");
            for (RegistroPrueba rp : reporte.getInscritos()) {
                System.out.println("Registro de Inscritos  " + rp.getCedula());
                fr.write(rp.getCedula() + " , " + rp.getRespuestaPrueba() + " , " + rp.getNotaRaven()
                        + " , " + rp.getNotaVerbal() + " , " + rp.getNotaMatematica()
                        + " , " + rp.getNotaTotal() + "," + (rp.getIsInscrito() ? "Si": "No" )
                        + "\n");
            }
            fr.close();
            request.getSession().setAttribute("reporte", path);
            request.setAttribute("reporte", path);
            return mapping.findForward("cvs");
        } catch (Exception e) {
            reporte.setMensaje(" Hay Problemas con el servidor.");
            return mapping.findForward("failure");
        }
    }

    private void imprimirArreglo(String[] tmp) {
        for (String string : tmp) {
            System.out.println("Imprimiendo arreglo" + string);
        }
    }
}
